import { useEventListener } from '@vueuse/core';
import { calcHypotenuse, calcVectorAngle } from '@/assets/js/utils';
import type { Point } from '@/assets/js/types';

export interface UseGestureOptions {
  target?: HTMLElement;
  scaleRatio?: number;
}

export function useGesture(useGestureOptions: UseGestureOptions = {}) {
  const { target = window, scaleRatio = 1.5 } = useGestureOptions;
  const startX = ref(0);
  const startY = ref(0);

  const primaryPointerX = ref(0);
  const primaryPointerY = ref(0);
  const secondaryPointerX = ref(0);
  const secondaryPointerY = ref(0);

  // 两指间的距离
  const distance = ref(0);

  // 缩放的距离差
  const distanceDiff = ref(0);

  // 上一次双指缩放的距离
  const prevDistance = ref(0);

  // 两指间的角度,和 (1, 0) 方向的夹角
  const rotateAngle = ref(0);

  // 旋转的夹角差
  const rotateAngleDiff = ref(0);

  // 上次两指间的角度,和 (1, 0) 方向的夹角
  const prevRotateAngle = ref(0);

  useEventListener(target, 'pointerdown', (event) => {
    if (event instanceof PointerEvent) {
      if (event.isPrimary) {
        startX.value = event.clientX;
        startY.value = event.clientY;
      }
    }
    event.stopPropagation();
    event.preventDefault();
  });

  useEventListener(target, 'pointerup', (event) => {
    if (event instanceof PointerEvent) {
      if (event.isPrimary) {
        primaryPointerX.value = 0;
        primaryPointerY.value = 0;
      } else {
        secondaryPointerX.value = 0;
        secondaryPointerY.value = 0;
      }
      distance.value = 0;
      distanceDiff.value = 0;
      prevDistance.value = 0;

      rotateAngle.value = 0;
      rotateAngleDiff.value = 0;
      prevRotateAngle.value = 0;
    }
    event.stopPropagation();
    event.preventDefault();
  });

  useEventListener(target, 'pointermove', (event) => {
    if (event instanceof PointerEvent) {
      if (event.isPrimary) {
        primaryPointerX.value = event.clientX;
        primaryPointerY.value = event.clientY;
      } else {
        secondaryPointerX.value = event.clientX;
        secondaryPointerY.value = event.clientY;
      }
      if (
        primaryPointerX.value &&
        primaryPointerY.value &&
        secondaryPointerX.value &&
        secondaryPointerY.value
      ) {
        const primaryPoint: Point = {
          x: primaryPointerX.value,
          y: primaryPointerY.value
        };
        const secondaryPoint: Point = {
          x: secondaryPointerX.value,
          y: secondaryPointerY.value
        };
        const hypotenuse = calcHypotenuse(primaryPoint, secondaryPoint);

        distance.value = hypotenuse;
        // 只有在有上次值时才进行计算
        if (prevDistance.value) {
          distanceDiff.value = (distance.value - prevDistance.value) * scaleRatio;
        }
        prevDistance.value = distance.value;

        const vectorAngle = calcVectorAngle(
          {
            x: secondaryPoint.x - primaryPoint.x,
            y: primaryPoint.y - secondaryPoint.y
          },
          {
            x: 1,
            y: 0
          }
        );
        rotateAngle.value = vectorAngle;
        if (prevRotateAngle.value) {
          // 处理角度的突变
          let diff = rotateAngle.value - prevRotateAngle.value;
          if (diff > 180) {
            diff -= 360;
          }
          if (diff < -180) {
            diff += 360;
          }
          rotateAngleDiff.value = diff;
        }
        prevRotateAngle.value = rotateAngle.value;
      }
    }
    event.stopPropagation();
    event.preventDefault();
  });
  return {
    distanceDiff,
    rotateAngleDiff
  };
}
